/* 
 同步编程：一般是因为只有一个线程，所以同时只能处理一件事情，上一件事情完成，下一件事情才可以继续处理
 异步编程：一般是因为有多个线程，所以可以同时处理多件事情
 浏览器是多线程的
   + GUI渲染线程：渲染解析html/css代码的
   + JS引擎线程：渲染解析js代码的
   + HTTP网络线程：从服务器获取资源的
   + 定时器监听线程：监听定时器是否到时间
   + ajax监听线程：监听ajax请求是否完成
   + 事件监听线程：监听事件是否触发
   + ...
 JS是单线程的：因为浏览器只分配一个“JS引擎线程（主线程）”用来渲染解析JS代码
   + 所以JS中大部分代码都是同步的
     + 循环操作
     + ...
   + 也存在异步编程的代码
     「异步宏任务」
        + setTimeout/setInterval
        + ajax/fetch
        + 事件绑定
        + ...
     「异步微任务」
        + requestAnimationFrame
        + IntersectionObserver
        + Promise
        + async/await
        + queueMicrotask
        + ...

 JS“单线程异步”的实现机制：EventLoop事件循环机制（借用了浏览器的某些线程）
 */

setTimeout(() => {
    console.log(1);
}, 20);
console.log(2);
setTimeout(() => {
    console.log(3);
}, 10);
console.log(4);
for (let i = 0; i < 90000000; i++) {
    // 需要79ms左右
}
console.log(5);
setTimeout(() => {
    console.log(6);
}, 8);
console.log(7);
setTimeout(() => {
    console.log(8);
}, 15);
console.log(9);


/* 
// 正常代码执行，两行代码的间隔时间是非常短的（在10微秒以内，甚至是不足1微秒），可以忽略不记！
console.time('AAA');
let a = 12;
let b = 13;
[a, b] = [b, a];
console.timeEnd('AAA'); //大概是9“微秒”左右 */

/* console.log(1);
setTimeout(() => {
    console.log(2);
}, 0); //定时器第二个参数设置为零(或者不写)也不是立即执行，而是需要等待5~7ms(浏览器的最快反应时间)
console.log(3); */

/* // 答案：1/3/2 因为定时器是异步操作
console.log(1);
setTimeout(() => {
    console.log(2);
}, 1000);
console.log(3); */

/* // 因为循环是同步操作，所以千万不要写“死循环”，这样其后面所有任务都无法继续执行了！！
console.log(1);
while (true) {
    // 死循环
}
console.log(2); */

/* // 循环是同步的：console.time/timeEnd可以计算出某一段程序执行需要的时间「受电脑此时性能的影响」
console.log(1);
console.time('AAA');
for (let i = 0; i < 999999999; i++) {
    if (i === 999999998) {
        console.log(2);
    }
}
console.timeEnd('AAA');
console.log(3); */

